<!DOCTYPE html>
<html lang="zh">
<head>
  <meta charset="UTF-8">
  <title>企业管理系统</title>
  <script src="https://cdn.jsdelivr.net/npm/vue@3/dist/vue.global.prod.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/axios/dist/axios.min.js"></script>
  <script src="https://cdn.jsdelivr.net/npm/echarts@5.6.0/dist/echarts.min.js"></script>
  <style>
    body {
      margin: 0;
      padding: 0;
      font-family: Arial, sans-serif;
      background-color: #f9f9f9;
    }

    .container {
      display: flex;
      min-height: 100vh;
    }

    /* 侧边栏样式 */
    .sidebar {
      width: 200px;
      background-color: #304156;
      color: white;
      padding: 20px 0;
    }

    .sidebar-header {
      padding: 0 20px;
      margin-bottom: 20px;
      font-size: 20px;
      font-weight: bold;
    }

    .nav-item {
      padding: 12px 20px;
      cursor: pointer;
      transition: background-color 0.3s;
    }

    .nav-item:hover {
      background-color: #263445;
    }

    .nav-item.active {
      background-color: #1890ff;
    }

    /* 主内容区域样式 */
    .main-content {
      flex: 1;
      padding: 20px;
      background-color: #f0f2f5;
    }

    .content-header {
      background-color: white;
      padding: 16px;
      margin-bottom: 20px;
      border-radius: 8px;
      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
    }

    /* 通用样式 */
    .btn {
      padding: 8px 16px;
      border: none;
      border-radius: 4px;
      cursor: pointer;
      transition: background-color 0.3s;
    }

    .btn-primary {
      background-color: #409EFF;
      color: white;
    }

    .btn-danger {
      background-color: #f56c6c;
      color: white;
    }

    .btn-cancel {
      background-color: #909399;
      color: white;
    }

    .btn:hover {
      opacity: 0.8;
    }

    /* 表格样式 */
    table {
      width: 100%;
      border-collapse: collapse;
      background: white;
      border-radius: 8px;
      overflow: hidden;
      box-shadow: 0 2px 8px rgba(0,0,0,0.05);
    }

    th, td {
      padding: 12px;
      text-align: left;
      border-bottom: 1px solid #f0f0f0;
    }

    th {
      background-color: #f2f2f2;
    }

    /* 弹窗样式 */
    .modal-overlay {
      position: fixed;
      top: 0;
      left: 0;
      width: 100vw;
      height: 100vh;
      background-color: rgba(0,0,0,0.5);
      display: flex;
      align-items: center;
      justify-content: center;
      z-index: 1000;
      backdrop-filter: blur(4px);
    }

    .modal {
      background: white;
      padding: 24px;
      border-radius: 12px;
      width: 480px;
      max-width: 90vw;
      max-height: 90vh;
      overflow-y: auto;
      box-shadow: 0 8px 24px rgba(0,0,0,0.15);
      animation: modalFadeIn 0.3s ease;
    }

    @keyframes modalFadeIn {
      from {
        opacity: 0;
        transform: translateY(-20px);
      }
      to {
        opacity: 1;
        transform: translateY(0);
      }
    }

    .modal h3 {
      margin-top: 0;
      color: #303133;
      border-bottom: 2px solid #EBEEF5;
      padding-bottom: 16px;
      margin-bottom: 24px;
      font-size: 20px;
      font-weight: 600;
    }

    .modal .form-group {
      margin-bottom: 20px;
    }

    .modal .form-group label {
      display: block;
      margin-bottom: 8px;
      color: #606266;
      font-weight: 500;
    }

    .modal .form-group input,
    .modal .form-group select {
      width: 100%;
      padding: 10px 12px;
      border: 1px solid #DCDFE6;
      border-radius: 6px;
      transition: all 0.3s;
      font-size: 14px;
    }

    .modal .form-group input:focus,
    .modal .form-group select:focus {
      border-color: #409EFF;
      outline: none;
      box-shadow: 0 0 0 2px rgba(64,158,255,0.2);
    }

    .modal .form-group input[type="file"] {
      padding: 8px;
      border: 2px dashed #DCDFE6;
      background: #F5F7FA;
      cursor: pointer;
    }

    .modal .form-group input[type="file"]:hover {
      border-color: #409EFF;
    }

    .modal .form-group img {
      margin-top: 12px;
      border: 2px solid #EBEEF5;
      transition: all 0.3s;
    }

    .modal .form-group img:hover {
      border-color: #409EFF;
    }

    .modal .btn-group {
      display: flex;
      justify-content: flex-end;
      gap: 12px;
      margin-top: 24px;
      padding-top: 16px;
      border-top: 1px solid #EBEEF5;
    }

    .modal .btn {
      padding: 10px 20px;
      font-size: 14px;
      font-weight: 500;
      border-radius: 6px;
      transition: all 0.3s;
    }

    .modal .btn-primary {
      background-color: #409EFF;
      color: white;
    }

    .modal .btn-primary:hover {
      background-color: #66b1ff;
      transform: translateY(-1px);
    }

    .modal .btn-cancel {
      background-color: #F5F7FA;
      color: #606266;
      border: 1px solid #DCDFE6;
    }

    .modal .btn-cancel:hover {
      background-color: #EBEEF5;
      color: #303133;
    }

    /* Toast提示样式 */
    .toast {
      position: fixed;
      top: 20px;
      left: 50%;
      transform: translateX(-50%);
      background-color: #67C23A;
      color: white;
      padding: 12px 24px;
      border-radius: 6px;
      box-shadow: 0 2px 8px rgba(0,0,0,0.15);
      z-index: 9999;
      transition: opacity 0.3s ease;
    }

    .toast.error {
      background-color: #F56C6C;
    }

    /* 搜索栏样式 */
    .search-bar {
      background: white;
      padding: 15px 20px;
      border-radius: 8px;
      box-shadow: 0 2px 4px rgba(0, 0, 0, 0.1);
      margin-bottom: 20px;
    }

    .search-bar form {
      display: flex;
      gap: 15px;
      align-items: center;
      flex-wrap: wrap;
    }

    .search-bar .form-group {
      display: flex;
      align-items: center;
      gap: 8px;
    }

    .search-bar input[type="text"],
    .search-bar select,
    .search-bar input[type="date"] {
      padding: 6px 12px;
      border: 1px solid #DCDFE6;
      border-radius: 4px;
      transition: all 0.3s;
    }

    /* 分页样式 */
    .pagination {
      display: flex;
      justify-content: center;
      align-items: center;
      margin-top: 20px;
      gap: 15px;
    }

    .pagination button {
      padding: 6px 12px;
      border: 1px solid #DCDFE6;
      background-color: white;
      color: #606266;
      border-radius: 4px;
      cursor: pointer;
    }

    .pagination button:disabled {
      background-color: #F5F7FA;
      color: #C0C4CC;
      cursor: not-allowed;
    }
  </style>
</head>
<body>
<div id="app">
  <!-- 顶部提示 -->
  <div v-if="toastMessage" :class="['toast', toastType]">
    {{ toastMessage }}
  </div>

  <div class="container">
    <!-- 侧边栏 -->
    <div class="sidebar">
      <div class="sidebar-header">企业管理系统</div>
      <div class="nav-item" 
           :class="{ active: currentView === 'home' }"
           @click="currentView = 'home'">
          首页
      </div>
      <div class="nav-item" 
           :class="{ active: currentView === 'dept' }"
           @click="currentView = 'dept'">
          部门管理
      </div>
      <div class="nav-item" 
           :class="{ active: currentView === 'emp' }"
           @click="currentView = 'emp'">
          员工管理
      </div>
      <div class="nav-item"
          :class="{active: currentView === 'report'}"
          @click="currentView = 'report'">
          数据展示
      </div>
    </div>

    <!-- 主内容区域 -->
    <div class="main-content">
      <!-- 首页 -->
      <div v-if="currentView === 'home'" class="content-header">
        <h2>欢迎使用企业管理系统</h2>
        <p>请从左侧菜单选择要管理的功能</p>
      </div>

      <!-- 部门管理 -->
      <div v-if="currentView === 'dept'">
        <div class="content-header">
          <h2>部门管理</h2>
        </div>
        
        <!-- 部门搜索栏 -->
        <div class="search-bar">
          <input v-model="deptSearchName" placeholder="搜索部门名" type="text">
          <button class="btn btn-primary" @click="fetchDepts">搜索</button>
        </div>

        <!-- 添加部门按钮 -->
        <button class="btn btn-primary" @click="openDeptForm">添加部门</button>

        <!-- 部门表格 -->
        <table>
          <thead>
            <tr>
              <th>ID</th>
              <th>名称</th>
              <th>创建时间</th>
              <th>更新时间</th>
              <th>操作</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="dept in filteredDepts" :key="dept.id">
              <td>{{ dept.id }}</td>
              <td>{{ dept.name }}</td>
              <td>{{ dept.createTime }}</td>
              <td>{{ dept.updateTime }}</td>
              <td>
                <button class="btn btn-primary" @click="editDept(dept)">修改</button>
                <button class="btn btn-danger" @click="deleteDept(dept.id)">删除</button>
              </td>
            </tr>
          </tbody>
        </table>
      </div>

      <!-- 员工管理 -->
      <div v-if="currentView === 'emp'">
        <div class="content-header">
          <h2>员工管理</h2>
        </div>

        <!-- 员工搜索栏 -->
        <form class="search-bar" @submit.prevent="searchEmp">
          <div class="form-group">
            <label for="name">姓名</label>
            <input type="text" id="name" v-model="empSearch.name" placeholder="请输入姓名">
          </div>

          <div class="form-group">
            <label for="gender">性别</label>
            <select id="gender" v-model="empSearch.gender">
              <option value="">不限</option>
              <option value="1">男</option>
              <option value="2">女</option>
            </select>
          </div>

          <div class="form-group">
            <label for="department">部门</label>
            <select id="department" v-model.number="empSearch.deptId">
              <option value="">不限</option>
              <option v-for="dept in depts" :key="dept.id" :value="dept.id">
                {{ dept.name }}
              </option>
            </select>
          </div>

          <div class="form-group">
            <label for="startTime">开始时间</label>
            <input type="date" id="startTime" v-model="empSearch.startDate">
            <label for="endTime">结束时间</label>
            <input type="date" id="endTime" v-model="empSearch.endDate">
          </div>

          <button type="submit" class="btn btn-primary">搜索</button>
        </form>

        <!-- 添加员工按钮 -->
        <button class="btn btn-primary" @click="openEmpForm">添加员工</button>
        <!-- 批量删除按钮 -->
        <button class="btn btn-primary" @click="deleteSelected">批量删除</button>

        <!-- 员工表格 -->
        <table v-if="emps.length">
          <thead>
            <tr>
              <th><input type="checkbox" :checked="selectAll" @change="toggleAll"/></th>
              <th>ID</th>
              <th>头像</th>
              <th>用户名</th>
              <th>姓名</th>
              <th>性别</th>
              <th>电话</th>
              <th>部门</th>
              <th>职位</th>
              <th>薪资</th>
              <th>入职日期</th>
              <th>操作</th>
            </tr>
          </thead>
          <tbody>
            <tr v-for="(emp, index) in emps" :key="emp.id">
              <td><input type="checkbox" class="rowCheckbox" v-model="emp.checked" @change="handleEmpSelect(emp)" /></td>
              <td>{{ getRowNumber(index) }}</td>
              <td>
                <img :src="emp.image || ''" 
                     width="40" height="40" 
                     style="border-radius: 50%; object-fit: cover;">
              </td>
              <td>{{ emp.username }}</td>
              <td>{{ emp.name }}</td>
              <td>{{ genderMap[emp.gender] }}</td>
              <td>{{ emp.phone }}</td>
              <td>{{ emp.dept }}</td>
              <td>{{ emp.job || '无' }}</td>
              <td>{{ emp.salary || '无' }}</td>
              <td>{{ emp.entryDate }}</td>
              <td>
                <button class="btn btn-primary" @click="editEmp(emp)">修改</button>
                <button class="btn btn-danger" @click="deleteEmp(emp.id)">删除</button>
              </td>
            </tr>
          </tbody>
        </table>
        <p v-else>暂无数据</p>

        <!-- 分页 -->
        <div class="pagination">
          <button @click="prevPage" :disabled="page === 1">上一页</button>
          <span>第 {{ page }} 页 / 共 {{ totalPages }} 页</span>
          <button @click="nextPage" :disabled="page === totalPages">下一页</button>
        </div>
      </div>

      <!-- 数据展示 -->
      <div v-if="currentView === 'report'" class="content-header">
        <h2>数据展示</h2>
        <div ref="jobChart" style="width: 100%; height: 400px;"></div>
        <!-- <div ref="deptChart" style="width: 100%; height: 400px; margin-top: 20px;"></div> -->
        <div ref="pieChart" style="width: 100%; height: 400px; margin-top: 20px; border: 1px solid #eee;"></div>
      </div>
    </div>
  </div>

  <!-- 部门表单弹窗 -->
  <div class="modal-overlay" v-if="showDeptForm">
    <div class="modal">
      <h3>{{ deptForm.id ? '修改部门' : '添加部门' }}</h3>
      <div class="form-group">
        <label>部门名称</label>
        <input v-model="deptForm.name" type="text">
      </div>
      <div class="btn-group">
        <button class="btn btn-primary" @click="saveDept">保存</button>
        <button class="btn btn-cancel" @click="showDeptForm = false">取消</button>
      </div>
    </div>
  </div>

  <!-- 员工表单弹窗 -->
  <div class="modal-overlay" v-if="showEmpForm">
    <div class="modal">
      <h3>{{ empForm.id ? '修改员工' : '添加员工' }}</h3>
      <form @submit.prevent="saveEmp">
        <div class="form-group">
          <label>头像</label>
          <input type="file" @change="handleAvatarUpload" accept="image/*">
          <img v-if="empForm.image" :src="empForm.image" width="100" height="100">
        </div>
        <div class="form-group">
          <label>用户名</label>
          <input v-model="empForm.username" type="text" required>
        </div>
        <div class="form-group">
          <label>姓名</label>
          <input v-model="empForm.name" type="text" required>
        </div>
        <div class="form-group">
          <label>性别</label>
          <select v-model="empForm.gender" required>
            <option value="1">男</option>
            <option value="2">女</option>
          </select>
        </div>
        <div class="form-group">
          <label>电话</label>
          <input v-model="empForm.phone" type="tel" required>
        </div>
        <div class="form-group">
          <label>部门</label>
          <select v-model="empForm.deptId" required>
            <option v-for="dept in depts" :key="dept.id" :value="dept.id">
              {{ dept.name }}
            </option>
          </select>
        </div>
        <div class="form-group">
          <label>职位</label>
          <select v-model="empForm.jobId" required>
            <option value="">请选择职位</option>
            <option v-for="job in empJobs" :key="job.id" :value="job.id">
              {{ job.name }}
            </option>
          </select>
        </div>
        <div class="form-group">
          <label>薪资</label>
          <input v-model="empForm.salary" type="number" required>
        </div>
        <div class="form-group">
          <label>入职日期</label>
          <input v-model="empForm.entryDate" type="date" required>
        </div>
        <!-- 添加工作经历部分 -->
        <div class="form-group">
          <label>工作经历</label>
          <div v-for="(exp, index) in empForm.children" :key="index" class="experience-item" style="margin-bottom: 15px; padding: 10px; border: 1px solid #DCDFE6; border-radius: 4px;">
            <div style="display: flex; justify-content: space-between; margin-bottom: 10px;">
              <h4 style="margin: 0;">经历 #{{index + 1}}</h4>
              <button type="button" class="btn btn-danger" @click="removeExperience(index)" style="padding: 2px 8px;">删除</button>
            </div>
            <div class="form-group">
              <label>开始日期</label>
              <input v-model="exp.begin" type="date" required>
            </div>
            <div class="form-group">
              <label>结束日期</label>
              <input v-model="exp.end" type="date" required>
            </div>
            <div class="form-group">
              <label>公司名称</label>
              <input v-model="exp.company" type="text" required>
            </div>
            <div class="form-group">
              <label>职位</label>
              <input v-model="exp.job" type="text" required>
            </div>
          </div>
          <button type="button" class="btn btn-primary" @click="addExperience" style="margin-top: 10px;">添加工作经历</button>
        </div>
        <div class="btn-group">
          <button type="submit" class="btn btn-primary">保存</button>
          <button type="button" class="btn btn-cancel" @click="showEmpForm = false">取消</button>
        </div>
      </form>
    </div>
  </div>
</div>

<script>
const { createApp, ref, computed, onMounted, watch } = Vue;

createApp({
  setup() {
    // 视图控制
    const currentView = ref('home');

    // 部门管理相关
    const depts = ref([]);
    const deptSearchName = ref('');
    const showDeptForm = ref(false);
    const deptForm = ref({ id: null, name: '' });

    //职位相关
    const empJobs = ref([]);

    // 员工管理相关
    const emps = ref([]);
    const selectedEmpIds = ref(new Set());
    const allEmpIds = ref(new Set()); // 存储所有员工的ID

    // 图表相关
    const jobChart = ref(null);
    const deptChart = ref(null);
    const pieChart = ref(null);
    let jobChartInstance = null;
    let deptChartInstance = null;
    let pieChartInstance = null;

    // 修改selectAll计算属性
    const selectAll = computed({
      get() {
        return emps.value.length > 0 && emps.value.every(emp => selectedEmpIds.value.has(emp.id));
      },
      set(value) {
        emps.value.forEach(emp => {
          if (value) {
            selectedEmpIds.value.add(emp.id);
          } else {
            selectedEmpIds.value.delete(emp.id);
          }
          emp.checked = value;
        });
      }
    });

    const empSearch = ref({
      name: '',
      gender: '',
      deptId: '',
      startDate: '',
      endDate: ''
    });
    const showEmpForm = ref(false);
    const empForm = ref({
      id: null,
      username: '',
      name: '',
      gender: '',
      phone: '',
      deptId: '',
      jobId: '',
      job: '',
      salary: '',
      entryDate: '',
      image: '',
      avatarFile: null,
      children: [] // 添加工作经历数组
    });

    // 分页相关
    const page = ref(1);
    const pageSize = ref(5);
    const total = ref(0);
    const totalPages = computed(() => Math.ceil(total.value / pageSize.value));

    // 添加序号计算属性
    const getRowNumber = (index) => {
      return (page.value - 1) * pageSize.value + index + 1;
    };

    // 提示消息
    const toastMessage = ref('');
    const toastType = ref('');

    const genderMap = {
      '1': '男',
      '2': '女'
    };

    // 通用方法
    const showToast = (msg, type = 'success') => {
      toastMessage.value = msg;
      toastType.value = type === 'success' ? '' : 'error';
      setTimeout(() => toastMessage.value = '', 3000);
    };

    // 部门管理方法
    const fetchDepts = () => {
      axios.get('/depts')
        .then(res => {
          depts.value = res.data.data;
        })
        .catch(() => showToast('获取部门失败', 'error'));
    };

    const filteredDepts = computed(() => {
      return depts.value.filter(dept =>
        dept.name.toLowerCase().includes(deptSearchName.value.toLowerCase())
      );
    });

    const openDeptForm = () => {
      deptForm.value = { id: null, name: '' };
      showDeptForm.value = true;
    };

    const editDept = (dept) => {
      deptForm.value = { ...dept };
      showDeptForm.value = true;
    };

    const saveDept = () => {
      const action = deptForm.value.id ? axios.put : axios.post;
      action('/depts', deptForm.value)
        .then(() => {
          fetchDepts();
          fetchEmps();
          showDeptForm.value = false;
          showToast(deptForm.value.id ? '修改成功' : '添加成功');
        })
        .catch(() => showToast('保存失败', 'error'));
    };

    const deleteDept = (id) => {
      if (confirm('确定删除该部门吗？')) {
        axios.delete(`/depts/${id}`)
          .then(() => {
            fetchDepts();
            showToast('删除成功');
          })
          .catch(() => showToast('删除失败', 'error'));
      }
    };

    // 职位相关
    // 获取职位列表
    const fetchEmpJobs = () => {
      axios.get('/jobs').then(res => {
        empJobs.value = res.data.data;
      }).catch(() => showToast('获取职位列表失败', 'error'));
    };

    // 员工管理方法
    //全选
    const toggleAll = () => {
      selectAll.value = !selectAll.value;
    };
    // 批量删除
    const deleteSelected = () => {
      if (selectedEmpIds.value.size === 0) {
        alert('请先选择要删除的员工');
        return;
      }

      if (confirm(`确定要删除选中的 ${selectedEmpIds.value.size} 名员工吗？`)) {
        axios.delete('/emps', {
          data: Array.from(selectedEmpIds.value)
        }).then(res => {
          fetchEmps();
          selectedEmpIds.value.clear();
          allEmpIds.value.clear();
          showToast("删除成功");
        }).catch(() => showToast("删除失败"));
      }
    };

    const fetchEmps = async () => {
      try {
        // 获取当前页数据
        const response = await axios.get('/emps', {
          params: {
            page: page.value,
            size: pageSize.value,
            name: empSearch.value.name || null,
            gender: empSearch.value.gender || null,
            deptId: empSearch.value.deptId || null,
            startDate: empSearch.value.startDate || null,
            endDate: empSearch.value.endDate || null
          }
        });
        
        if (response.data.code === 1) {
          // 更新员工数据，同时保持选中状态
          emps.value = response.data.data.rows.map(emp => ({
            ...emp,
            checked: selectedEmpIds.value.has(emp.id)
          }));
          total.value = response.data.data.total;
        } else {
          showToast(response.data.msg || '获取数据失败', 'error');
        }
      } catch (error) {
        console.error('获取员工列表失败:', error);
        showToast('网络连接失败，请检查服务器是否正常运行', 'error');
      }
    };

    const searchEmp = async () => {
      try {
        page.value = 1;
        selectedEmpIds.value.clear(); // 搜索时清空选中状态
        const response = await axios.get('/emps', {
          params: {
            page: page.value,
            size: pageSize.value,
            name: empSearch.value.name || null,
            gender: empSearch.value.gender || null,
            deptId: empSearch.value.deptId || null,
            startDate: empSearch.value.startDate || null,
            endDate: empSearch.value.endDate || null
          }
        });
        
        if (response.data.code === 1) {
          emps.value = response.data.data.rows.map(emp => ({
            ...emp,
            checked: selectedEmpIds.value.has(emp.id)
          }));
          total.value = response.data.data.total;
        } else {
          showToast(response.data.msg || '查询失败', 'error');
        }
      } catch (error) {
        console.error('搜索员工失败:', error);
        showToast('网络连接失败，请检查服务器是否正常运行', 'error');
      }
    };

    const openEmpForm = () => {
      empForm.value = {
        id: null,
        username: '',
        name: '',
        gender: '',
        phone: '',
        deptId: '',
        jobId: '',
        job: '',
        salary: '',
        entryDate: '',
        image: '',
        avatarFile: null,
        children: [] // 重置工作经历
      };
      showEmpForm.value = true;
    };

    const editEmp = async (emp) => {
      try {
        console.log('开始获取员工详情，员工ID:', emp.id);
        // 获取员工的详细信息，包括工作经历
        const response = await axios.get(`/emps/${emp.id}`);
        console.log('获取员工详情响应:', response);
        
        if (response.data.code === 1) {
          const empDetail = response.data.data;
          console.log('员工详情数据:', empDetail);
          
          // 确保工作经历数据存在
          if (!empDetail.children) {
            empDetail.children = [];
          }
          
          // 处理部门ID和入职日期
          const deptId = empDetail.deptId || empDetail.dept_id;
          const entryDate = empDetail.entryDate || empDetail.entry_date;
          const jobId = empDetail.jobId || empDetail.job_id;
          
          // 格式化日期（如果存在）
          const formattedEntryDate = entryDate ? new Date(entryDate).toISOString().split('T')[0] : '';
          
          empForm.value = {
            ...empDetail,
            deptId: deptId,
            jobId: jobId,
            entryDate: formattedEntryDate,
            children: empDetail.children || []
          };
          
          // 保存原始数据用于比较
          empForm.value._originalData = JSON.parse(JSON.stringify(empForm.value));
          
          console.log('设置到表单的数据:', empForm.value);
          showEmpForm.value = true;
        } else {
          console.error('获取员工详情失败，响应码:', response.data.code, '错误信息:', response.data.msg);
          showToast(response.data.msg || '获取员工详情失败', 'error');
        }
      } catch (error) {
        console.error('获取员工详情失败:', error);
        showToast('获取员工详情失败', 'error');
      }
    };

    const handleAvatarUpload = (event) => {
      const file = event.target.files[0];
      if (!file) return;
      
      const reader = new FileReader();
      reader.onload = (e) => {
        empForm.value.image = e.target.result;
      };
      reader.readAsDataURL(file);
      
      empForm.value.avatarFile = file;
    };

    const saveEmp = async () => {
      try {
        let imageUrl = empForm.value.image;
        
        // 处理头像上传
        if (empForm.value.avatarFile) {
          const formData = new FormData();
          formData.append('file', empForm.value.avatarFile);
          const uploadRes = await axios.post('/upload', formData, {
            headers: { 'Content-Type': 'multipart/form-data' }
          });
          imageUrl = uploadRes.data.data;
        }

        // 准备提交数据
        const submitData = {
          id: empForm.value.id,
          deptId: empForm.value.deptId,
          jobId: empForm.value.jobId // 添加jobId
        };

        // 如果是新增，则提交所有数据
        if (!empForm.value.id) {
          Object.assign(submitData, {
            username: empForm.value.username,
            name: empForm.value.name,
            gender: empForm.value.gender,
            phone: empForm.value.phone,
            jobId: empForm.value.jobId,
            salary: empForm.value.salary,
            entryDate: empForm.value.entryDate,
            image: imageUrl,
            children: empForm.value.children
          });
        } else {
          // 如果是修改，只提交发生变化的字段
          const originalData = empForm.value._originalData;
          
          // 比较每个字段是否发生变化
          if (empForm.value.username !== originalData.username) submitData.username = empForm.value.username;
          if (empForm.value.name !== originalData.name) submitData.name = empForm.value.name;
          if (empForm.value.gender !== originalData.gender) submitData.gender = empForm.value.gender;
          if (empForm.value.phone !== originalData.phone) submitData.phone = empForm.value.phone;
          if (empForm.value.jobId !== originalData.jobId) submitData.jobId = empForm.value.jobId;
          if (empForm.value.salary !== originalData.salary) submitData.salary = empForm.value.salary;
          if (empForm.value.entryDate !== originalData.entryDate) submitData.entryDate = empForm.value.entryDate;
          if (imageUrl !== originalData.image) submitData.image = imageUrl;
          
          // 比较工作经历的变化
          const originalChildren = originalData.children || [];
          const currentChildren = empForm.value.children || [];
          
          // 找出新增、修改和删除的工作经历
          const modifiedChildren = currentChildren.map(child => {
            const originalChild = originalChildren.find(oc => oc.id === child.id);
            if (!originalChild) {
              // 新增的工作经历
              return { ...child, empId: empForm.value.id };
            }
            
            // 检查是否有修改
            const changes = {};
            if (child.begin !== originalChild.begin) changes.begin = child.begin;
            if (child.end !== originalChild.end) changes.end = child.end;
            if (child.company !== originalChild.company) changes.company = child.company;
            if (child.job !== originalChild.job) changes.job = child.job;
            
            // 如果有修改，返回修改后的数据
            return Object.keys(changes).length > 0 ? { ...child, ...changes } : null;
          }).filter(Boolean);
          
          // 找出删除的工作经历
          const deletedChildren = originalChildren
            .filter(oc => !currentChildren.some(child => child.id === oc.id))
            .map(child => ({ id: child.id, _delete: true }));
          
          // 合并所有工作经历的变化
          if (modifiedChildren.length > 0 || deletedChildren.length > 0) {
            submitData.children = [...modifiedChildren, ...deletedChildren];
          }
        }

        // 删除不需要的字段
        delete submitData.avatarFile;
        delete submitData._originalData;

        const url = '/emps';
        const response = empForm.value.id ? 
            await axios.put(url, submitData) : 
            await axios.post(url, submitData);
        
        if (response.data.code === 1) {
            showToast('保存成功');
            showEmpForm.value = false;
            fetchEmps();
        } else {
            showToast(response.data.msg || '保存失败', 'error');
        }
      } catch (error) {
        console.error('保存员工失败:', error);
        showToast('保存失败', 'error');
      }
    };

    const deleteEmp = (id) => {
      if (confirm('确定要删除该员工吗？')) {
        axios.delete(`/emps`, {
          data: [id],
        })
          .then(() => {
            showToast('删除成功');
            fetchEmps();
          })
          .catch(() => showToast('删除失败', 'error'));
      }
    };

    const prevPage = () => {
      if (page.value > 1) {
        page.value--;
        fetchEmps();
      }
    };

    const nextPage = () => {
      if (page.value < totalPages.value) {
        page.value++;
        fetchEmps();
      }
    };

    // 修改initChart函数
    const initChart = async () => {
      try {
        console.log('开始初始化图表...');
        
        // 初始化职位分布图表
        if (jobChart.value) {
          console.log('初始化职位分布图表...');
          jobChartInstance = echarts.init(jobChart.value);
          const jobResponse = await axios.get('/report/empJobData');
          console.log('职位数据响应:', jobResponse);
          
          if (jobResponse.data.code !== 1) {
            throw new Error(jobResponse.data.msg || '获取职位数据失败');
          }
          
          const jobData = jobResponse.data.data;
          console.log('职位数据:', jobData);
          
          if (!jobData || !jobData.jobList || !jobData.dataList) {
            throw new Error('职位数据格式不正确');
          }

          const jobOption = {
            title: {
              text: '职位分布统计'
            },
            tooltip: {
              trigger: 'axis',
              axisPointer: {
                type: 'shadow'
              }
            },
            legend: {
              data: ['员工数量']
            },
            xAxis: {
              type: 'category',
              data: jobData.jobList,
              axisLabel: {
                interval: 0,
                rotate: 30
              }
            },
            yAxis: {
              type: 'value',
              name: '员工数量'
            },
            series: [
              {
                name: '员工数量',
                type: 'bar',
                data: jobData.dataList,
                itemStyle: {
                  color: '#409EFF'
                }
              }
            ]
          };

          jobChartInstance.setOption(jobOption);
          console.log('职位分布图表初始化完成');
        }

        // 初始化部门分布图表
        if (deptChart.value) {
          console.log('初始化部门分布图表...');
          deptChartInstance = echarts.init(deptChart.value);
          const deptResponse = await axios.get('/report/empDeptData');
          console.log('部门数据响应:', deptResponse);
          
          if (deptResponse.data.code !== 1) {
            throw new Error(deptResponse.data.msg || '获取部门数据失败');
          }
          
          const deptData = deptResponse.data.data;
          console.log('部门数据:', deptData);
          
          // 检查数据结构
          if (!deptData) {
            throw new Error('部门数据为空');
          }
          
          // 检查并转换数据格式
          let deptList = [];
          let dataList = [];
          
          if (Array.isArray(deptData)) {
            // 如果返回的是数组，需要转换格式
            deptList = deptData.map(item => item.name || item.deptName);
            dataList = deptData.map(item => item.count || item.value);
          } else if (deptData.deptList && deptData.dataList) {
            // 如果返回的是对象格式
            deptList = deptData.deptList;
            dataList = deptData.dataList;
          } else {
            throw new Error('部门数据格式不正确，无法解析');
          }
          
          console.log('处理后的部门数据:', { deptList, dataList });
        }

        // 初始化性别分布饼图
        if (pieChart.value) {
          console.log('初始化性别分布饼图...');
          pieChartInstance = echarts.init(pieChart.value);
          
          try {
            // 从后端获取性别数据
            const genderResponse = await axios.get('/report/empGenderData');
            console.log('性别数据响应:', genderResponse);
            
            if (genderResponse.data.code !== 1) {
              throw new Error(genderResponse.data.msg || '获取性别数据失败');
            }
            
            // 转换数据格式
            const genderData = genderResponse.data.data.genderList.map((gender, index) => ({
              name: gender,
              value: genderResponse.data.data.dataList[index]
            }));

            console.log('处理后的性别数据:', genderData);

            const pieOptionGender = {
              title: {
                text: '员工性别分布',
                left: 'center',
                top: 10
              },
              tooltip: {
                trigger: 'item',
                formatter: '{a} <br/>{b}: {c}人 ({d}%)'
              },
              legend: {
                orient: 'vertical',
                left: 'left',
                top: 'middle'
              },
              series: [
                {
                  name: '性别分布',
                  type: 'pie',
                  radius: ['40%', '70%'],
                  center: ['60%', '50%'],
                  avoidLabelOverlap: false,
                  padAngle: 5,
                  itemStyle: {
                    borderRadius: 10,
                    borderColor: '#fff',
                    borderWidth: 2
                  },
                  label: {
                    show: true,
                    position: 'outside',
                    formatter: '{b}: {c}人'
                  },
                  emphasis: {
                    scale: true,
                    scaleSize: 5,
                    label: {
                      show: true,
                      fontSize: 20,
                      fontWeight: 'bold',
                      position: 'center',
                      formatter: '{b}',
                      backgroundColor: 'rgba(255, 255, 255, 0.8)',
                      padding: [10, 15],
                      borderRadius: 5
                    },
                    itemStyle: {
                      shadowBlur: 10,
                      shadowOffsetX: 0,
                      shadowColor: 'rgba(0, 0, 0, 0.5)'
                    }
                  },
                  labelLine: {
                    show: true,
                    length: 10,
                    length2: 10
                  },
                  data: genderData
                }
              ]
            };

            pieChartInstance.setOption(pieOptionGender);
            console.log('性别分布饼图初始化完成');
          } catch (error) {
            console.error('初始化性别分布饼图失败:', error);
            showToast('初始化性别分布饼图失败: ' + error.message, 'error');
          }
        }

        // 添加窗口大小变化时的自适应
        window.addEventListener('resize', () => {
          if (jobChartInstance) {
            jobChartInstance.resize();
          }
          if (deptChartInstance) {
            deptChartInstance.resize();
          }
          if (pieChartInstance) {
            pieChartInstance.resize();
          }
        });
      } catch (error) {
        console.error('图表初始化失败:', error);
        showToast(error.message || '获取图表数据失败', 'error');
      }
    };

    // 添加工作经历
    const addExperience = () => {
      empForm.value.children.push({
        id: null,
        begin: '',
        end: '',
        company: '',
        job: '',
        empId: empForm.value.id // 如果是编辑状态，添加当前员工ID
      });
    };

    // 删除工作经历
    const removeExperience = async (index) => {
      const exp = empForm.value.children[index];
      if (exp.id) {
        // 如果经历有ID，说明是已保存的经历，需要调用后端删除
        try {
          await axios.delete(`/emps/${exp.id}`);
          showToast('删除工作经历成功');
        } catch (error) {
          console.error('删除工作经历失败:', error);
          showToast('删除工作经历失败', 'error');
          return; // 如果删除失败，不从前端移除
        }
      }
      empForm.value.children.splice(index, 1);
    };

    // 修改单个选择处理函数
    const handleEmpSelect = (emp) => {
      if (emp.checked) {
        selectedEmpIds.value.add(emp.id);
      } else {
        selectedEmpIds.value.delete(emp.id);
      }
    };

    // 监听视图变化
    watch(currentView, (newView) => {
      if (newView === 'report') {
        console.log('切换到报表视图，准备初始化图表...');
        // 确保DOM已经更新后再初始化图表
        setTimeout(() => {
          initChart();
        }, 100); // 增加延迟时间，确保DOM完全渲染
      }
    });

    // 初始化
    fetchDepts();
    fetchEmps();

    // 在组件挂载时获取职位列表
    onMounted(() => {
      fetchEmpJobs();
    });

    return {
      currentView,
      depts,
      deptSearchName,
      filteredDepts,
      showDeptForm,
      deptForm,
      emps,
      empSearch,
      showEmpForm,
      empForm,
      page,
      totalPages,
      total,
      genderMap,
      toastMessage,
      toastType,
      empJobs,
      fetchDepts,
      openDeptForm,
      editDept,
      saveDept,
      deleteDept,
      searchEmp,
      openEmpForm,
      editEmp,
      saveEmp,
      deleteEmp,
      handleAvatarUpload,
      prevPage,
      nextPage,
      addExperience,
      removeExperience,
      //复选框
      selectAll,
      toggleAll,
      //批量删除
      deleteSelected,
      getRowNumber,
      handleEmpSelect,

      //数据
      initChart,
      jobChart,
      deptChart,
      pieChart
    };
  }
}).mount('#app');
</script>
</body>
</html>